package com.kakarote.hrm.task;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.kakarote.hrm.constant.EmployeeEncryptFieldTypeEnum;
import com.kakarote.hrm.entity.PO.HrmEmployeeData;
import com.kakarote.hrm.entity.PO.HrmEmployeeDataIntegrity;
import com.kakarote.hrm.entity.PO.HrmEmployeeEncryptField;
import com.kakarote.hrm.mapper.*;
import com.kakarote.hrm.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author 92487
 * @Date 2024/3/13 20:31
 */

@Component
@EnableScheduling
@EnableAsync
@Slf4j
public class EmployeeDataIntegrityTotalTask {

    @Resource
    private IHrmEmployeeService employeeService;

    @Autowired
    private IHrmEmployeeDataService employeeDataService;

    @Autowired
    private IHrmEmployeeEncryptFieldService employeeEncryptFieldService;

    @Autowired
    private IHrmEmployeeConcurrentPostService employeeConcurrentPostService;

    @Autowired
    private HrmEmployeeEducationExperienceMapper employeeEducationExperienceMapper;

    @Autowired
    private HrmEmployeeWorkExperienceMapper employeeWorkExperienceMapper;

    @Autowired
    private HrmEmployeePostMapper employeePostMapper;

    @Autowired
    private HrmEmployeeTechnicalMapper employeeTechnicalMapper;

    @Autowired
    private HrmEmployeeSpecialWorkerMapper employeeSpecialWorkerMapper;

    @Autowired
    private IHrmEmployeeContactsService contactsService;

    @Autowired
    private HrmEmployeeDataIntegrityMapper employeeDataIntegrityMapper;



    @Scheduled(cron = "0 0 3 * * ? ")
    public void employeeDataIntegrityTotalTask() {
//        List<Long> employeeIds = Lists.newArrayList(1759049660328071168L);
        List<Long> employeeIds = Lists.newArrayList();
        //查询员工固定列表
        List<Map<String, Object>> employeeList = employeeService.queryEmployeeFixedField(employeeIds);

        //字段信息
        List<HrmEmployeeEncryptField> fieldList = employeeEncryptFieldService.lambdaQuery().list();
        Map<Integer, List<HrmEmployeeEncryptField>> fieldGroup = new HashMap<>();
        if (fieldList != null && !fieldList.isEmpty()) {
            fieldGroup = fieldList.stream().collect(Collectors.groupingBy(HrmEmployeeEncryptField::getType, Collectors.toList()));
        }
        log.info("字段信息查询完成");
        //自定义字段
        List<HrmEmployeeData> dataList = employeeDataService.queryEmployeeDataList(employeeIds);
        Map<Long, List<HrmEmployeeData>> dataGroup = new HashMap<>();
        if (dataList != null && !dataList.isEmpty()) {
            dataGroup = dataList.stream().collect(Collectors.groupingBy(HrmEmployeeData::getEmployeeId));
        }
        log.info("自定义字段查询完成");
        //兼职信息
        List<Map<String, Object>> concurrentPostList = employeeConcurrentPostService.queryEmployeeConcurrentPostListMap(employeeIds);
        Map<Long, List<Map<String, Object>>> concurrentPostGroup = new HashMap<>();
        if (concurrentPostList != null && !concurrentPostList.isEmpty()) {
            concurrentPostGroup = concurrentPostList.stream().collect(Collectors.groupingBy(map -> Long.parseLong(map.get("employeeId").toString())));
        }
        log.info("兼职信息查询完成");
        // 教育信息
        List<Map<String, Object>> educationExperienceList = employeeEducationExperienceMapper.queryEmployeeEducationExperienceListMap(employeeIds);
        Map<Long, List<Map<String, Object>>> educationExperienceGroup = new HashMap<>();
        if (educationExperienceList != null && !educationExperienceList.isEmpty()) {
            educationExperienceGroup = educationExperienceList.stream().collect(Collectors.groupingBy(map -> Long.parseLong(map.get("employeeId").toString())));
        }
        log.info("教育信息查询完成");
        // 工作信息
        List<Map<String, Object>> workExperienceList = employeeWorkExperienceMapper.queryEmployeeWorkExperienceListMap(employeeIds);
        Map<Long, List<Map<String, Object>>> workExperienceGroup = new HashMap<>();
        if (workExperienceList != null && !workExperienceList.isEmpty()) {
            workExperienceGroup = workExperienceList.stream().collect(Collectors.groupingBy(map -> Long.parseLong(map.get("employeeId").toString())));
        }
        log.info("工作信息查询完成");
        // 职（执）业资格
        List<Map<String, Object>> certificateList = employeePostMapper.queryEmployeeCertificateListMap(employeeIds);
        Map<Long, List<Map<String, Object>>> certificateGroup = new HashMap<>();
        if (certificateList != null && !certificateList.isEmpty()) {
            certificateGroup = certificateList.stream().collect(Collectors.groupingBy(map -> Long.parseLong(map.get("employeeId").toString())));
        }
        log.info("职（执）业资格信息查询完成");
        // 专业技术资格
        List<Map<String, Object>> technicalList =  employeeTechnicalMapper.queryEmployeeTechnicalListMap(employeeIds);
        Map<Long, List<Map<String, Object>>> technicalGroup = new HashMap<>();
        if (technicalList != null && !technicalList.isEmpty()) {
            technicalGroup = technicalList.stream().collect(Collectors.groupingBy(map -> Long.parseLong(map.get("employeeId").toString())));
        }
        log.info("专业技术资格信息查询完成");
        //专业技术工人证书
        List<Map<String, Object>>  specialWorkerList = employeeSpecialWorkerMapper.queryEmployeeSpecialWorkerListMap(employeeIds);
        Map<Long, List<Map<String, Object>>> specialWorkerGroup = new HashMap<>();
        if (specialWorkerList != null && !specialWorkerList.isEmpty()) {
            specialWorkerGroup = specialWorkerList.stream().collect(Collectors.groupingBy(map -> Long.parseLong(map.get("employeeId").toString())));
        }
        log.info("专业技术工人证书信息查询完成");
        // 家庭成员及主要社会关系
        List<Map<String, Object>>  contactsList = contactsService.queryEmployeeContactsListMap(employeeIds);
        Map<Long, List<Map<String, Object>>> contactsGroup = new HashMap<>();
        if (contactsList != null && !contactsList.isEmpty()) {
            contactsGroup = contactsList.stream().collect(Collectors.groupingBy(map -> Long.parseLong(map.get("employeeId").toString())));
        }
        log.info("家庭成员及主要社会关系信息查询完成");

        // 岗位字段
        List<HrmEmployeeEncryptField> fields = Optional.ofNullable(fieldGroup.get(EmployeeEncryptFieldTypeEnum.POST.getValue())).orElse(new ArrayList<>());
        // 基本信息字段
        List<HrmEmployeeEncryptField> baseFields = Optional.ofNullable(fieldGroup.get(EmployeeEncryptFieldTypeEnum.BASE.getValue())).orElse(new ArrayList<>());
        fields.addAll(baseFields);
        // 紧急联系人字段
        List<HrmEmployeeEncryptField> emergencyContactFields = Optional.ofNullable(fieldGroup.get(EmployeeEncryptFieldTypeEnum.EMERGENCYCONTACT.getValue())).orElse(new ArrayList<>());
        fields.addAll(emergencyContactFields);

        // 员工数据完整度
        List<HrmEmployeeDataIntegrity> totalList = new ArrayList<>();
        log.info("员工数据完整度计算完成");
        for (Map<String, Object> empMap : employeeList) {
            //总字段数
            Integer fieldTotal = 0;
            //非空字段数
            Integer fieldNotNull = 0;

            Long employeeId = Long.parseLong(empMap.get("employeeId").toString());
            List<HrmEmployeeData> employeeDataList = dataGroup.get(employeeId);
            Map<String, String> dataMap = employeeDataList.stream().collect(Collectors.toMap(HrmEmployeeData::getFieldName, entry -> Optional.ofNullable(entry.getFieldValue()).orElse("")));

            fieldTotal += fields.size();
            for (HrmEmployeeEncryptField field : fields) {
                if (dataMap.containsKey(field.getFieldName())) {
                    if (StrUtil.isNotEmpty(dataMap.get(field.getFieldName()))) {
                        fieldNotNull++;
                    }
                } else {
                    Object o = empMap.get(StrUtil.toCamelCase(field.getFieldName()));
                    if (o != null && StrUtil.isNotEmpty(o.toString())) {
                        fieldNotNull++;
                    }
                }
            }

            for (EmployeeEncryptFieldTypeEnum value : EmployeeEncryptFieldTypeEnum.values()) {
                List<Map<String, Object>> listMap = new ArrayList<>();
                List<HrmEmployeeEncryptField> empFieldList = new ArrayList<>();
                switch (value) {
                    case SIDELINE:
                        // 兼职信息
                        listMap = concurrentPostGroup.get(employeeId);
                        empFieldList = fieldGroup.get(EmployeeEncryptFieldTypeEnum.SIDELINE.getValue());
                        break;
                    case EDUCATION:
                        // 教育信息
                        listMap = educationExperienceGroup.get(employeeId);
                        empFieldList = fieldGroup.get(EmployeeEncryptFieldTypeEnum.EDUCATION.getValue());
                        break;
                    case WORK:
                        // 工作信息
                        listMap = workExperienceGroup.get(employeeId);
                        empFieldList = fieldGroup.get(EmployeeEncryptFieldTypeEnum.WORK.getValue());
                        break;
                    case CERTIFICATE:
                        // 职（执）业资格
                        listMap = certificateGroup.get(employeeId);
                        empFieldList = fieldGroup.get(EmployeeEncryptFieldTypeEnum.CERTIFICATE.getValue());
                        break;
                    case TECHNICAL:
                        // 专业技术资格
                        listMap = technicalGroup.get(employeeId);
                        empFieldList = fieldGroup.get(EmployeeEncryptFieldTypeEnum.TECHNICAL.getValue());
                        break;
                    case TECHNICALWORKER:
                        // 专业技术工人证书
                        listMap = specialWorkerGroup.get(employeeId);
                        empFieldList = fieldGroup.get(EmployeeEncryptFieldTypeEnum.TECHNICALWORKER.getValue());
                        break;
                    case CONTACTS:
                        // 家庭成员及主要社会关系
                        listMap = contactsGroup.get(employeeId);
                        empFieldList = fieldGroup.get(EmployeeEncryptFieldTypeEnum.CONTACTS.getValue());
                        break;
                }
                if (listMap != null && !listMap.isEmpty()){
                    fieldTotal += empFieldList.size() * listMap.size();
                    for (Map<String, Object> map : listMap) {
                        for (HrmEmployeeEncryptField field : empFieldList) {
                            String fieldName = StrUtil.toCamelCase(field.getFieldName());
                            if (map.containsKey(fieldName) &&
                                    map.get(fieldName) != null &&
                                    StrUtil.isNotEmpty(map.get(fieldName).toString())){
                                fieldNotNull++;
                            }
                        }
                    }

                }else {
                    if (value.getValue() == EmployeeEncryptFieldTypeEnum.CONTACTS.getValue()
                            || value.getValue() == EmployeeEncryptFieldTypeEnum.WORK.getValue()
                            || value.getValue() == EmployeeEncryptFieldTypeEnum.EDUCATION.getValue()){
                        fieldTotal += empFieldList.size();
                    }
                }
            }
            // 计算数据完整度
            HrmEmployeeDataIntegrity dataIntegrity = new HrmEmployeeDataIntegrity();
            dataIntegrity.setEmployeeId(employeeId);
            dataIntegrity.setDataIntegrity(new BigDecimal(fieldNotNull).divide(new BigDecimal(fieldTotal), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
            dataIntegrity.setDate(LocalDate.now().minusDays(1).toString());
            dataIntegrity.setCreateTime(LocalDateTime.now());
            totalList.add(dataIntegrity);
        }
        if (!totalList.isEmpty()){
            employeeDataIntegrityMapper.batchInsert(totalList);
        }
        log.info("定时任务统计员工数据完整度完成");
        this.deleteDataIntegrity();
        log.info("只保留当月的数据和之前每一个月份最后一天的数据");
    }


    /**
     * 只保留当月的数据和之前每一个月份最后一天的数据，其余数据删除
     */
    public void deleteDataIntegrity() {
        List<String> dateList = employeeDataIntegrityMapper.queryDataIntegrityAllDate();
        for (String dataDate : dateList) {
            if (!isLastDayOfMonthOrCurrentMonth(dataDate)) {
                System.out.println(dataDate);
                employeeDataIntegrityMapper.deleteDataIntegrityByDate(dataDate);
            }
        }
    }

    // 判断日期是否为当月或之前每个月的最后一天
    private boolean isLastDayOfMonthOrCurrentMonth(String dateStr) {
        LocalDate date = LocalDate.parse(dateStr);
        LocalDate today = LocalDate.now();
        LocalDate lastDayOfMonth = date.withDayOfMonth(date.lengthOfMonth());

        // 如果是当月，则直接返回 true
        if (date.getMonth() == today.getMonth() && date.getYear() == today.getYear()) {
            return true;
        }
        return date.equals(lastDayOfMonth);
    }

}
